#证书认证管理合约 Vyper版本，以下是对比solidity的主要不同
#没有枚举，只能用常量代替 ，没有动态数组，状态变量定义时不能赋值
#没有继承，只有把owner合约代码copy进来，没有modifier，只有copy代码
#没有无固定大小数组，只能预先定义一个数组的大小，超过了再想办法
#如果公共状态变量是一个结构类型，编译器生成的getter函数也不同。

#定义一个结构，结构定义在事件和状态变量之前
struct CertInfo:
    status:uint256
    lastTime:timestamp

#常量是全局变量，不属于状态变量，不能用self 全局变量也可以放在事件后面
#Inexistence:constant(uint256) = 0  #未用上
#定义两种状态
Issued:constant(uint256) = 1
Revoked:constant(uint256) = 2

#定义各种事件
OwnershipTransferred:event({_from:indexed(address),_to:indexed(address)})
PauseTransferred:event({_isPause:bool})
setNewOwner:event({_newOwner:address})
DocumentIssued:event({_document:indexed(bytes32)})
DocumentRevoked:event({_document:indexed(bytes32)})

#定义状态变量
#主管理员
majorOwner:public(address)
#副管理员
minorOwner:public(address)
#更换主管理员
newMajorOwner:public(address)
#更换副管理员
newMinorOwner:public(address)
#是否暂停
isPause:public(bool)
#name
name:public(string[100])
#version
version:public(string[100])
#每个证书的信息
documentInfos:public(map(bytes32,CertInfo))

#constructor
@public
def __init__(_name:string[20]):
    self.majorOwner = msg.sender
    self.minorOwner = msg.sender
    self.isPause = True
    self.name = _name
    self.version = "1.0.0"

@public
def pause():
    assert msg.sender == self.majorOwner or msg.sender == self.minorOwner,"permission denied"
    assert not self.isPause,'contract is paused'
    self.isPause = True
    log.PauseTransferred(True)

@public
def unPause():
    assert msg.sender == self.majorOwner or msg.sender == self.minorOwner,"permission denied"
    assert self.isPause,'contract is unPaused'
    self.isPause = False
    log.PauseTransferred(False)

@public
def transferMajorOwnership(_newMajorOwner:address):
    assert msg.sender == self.majorOwner
    assert _newMajorOwner != ZERO_ADDRESS , "zero address"
    self.newMajorOwner = _newMajorOwner
    log.setNewOwner(_newMajorOwner)

@public
def acceptMajorOwnership():
    assert self.newMajorOwner != ZERO_ADDRESS , "zero address"
    assert msg.sender == self.newMajorOwner, "permission denied"
    log.OwnershipTransferred(self.majorOwner,msg.sender)
    self.majorOwner = msg.sender
    self.newMajorOwner = ZERO_ADDRESS

@public
def transferMinorOwnership(_newMinorOwner:address):
    assert msg.sender == self.majorOwner or msg.sender == self.minorOwner,"permission denied"
    assert _newMinorOwner != ZERO_ADDRESS , "zero address"
    self.newMinorOwner = _newMinorOwner
    log.setNewOwner(_newMinorOwner)

@public
def acceptMinorOwnership():
    assert self.newMinorOwner != ZERO_ADDRESS , "zero address"
    assert msg.sender == self.newMinorOwner, "permission denied"
    log.OwnershipTransferred(self.minorOwner,msg.sender)
    self.minorOwner = msg.sender
    self.newMinorOwner = ZERO_ADDRESS

@public
@constant
def isIssued(_document:bytes32) -> bool:
    return self.documentInfos[_document].status == Issued

@public
def issue(_document:bytes32):
    assert msg.sender == self.majorOwner or msg.sender == self.minorOwner,"permission denied"
    assert not self.isPause,'contract is paused'
    assert not self.isIssued(_document) , 'has issued'
    self.documentInfos[_document].status = Issued
    self.documentInfos[_document].lastTime = block.timestamp
    log.DocumentIssued(_document)

@public
def revoke(_document:bytes32):
    assert msg.sender == self.majorOwner or msg.sender == self.minorOwner,"permission denied"
    assert not self.isPause,'contract is paused'
    assert self.isIssued(_document) , 'not issued'
    self.documentInfos[_document].status = Revoked
    self.documentInfos[_document].lastTime = block.timestamp
    log.DocumentRevoked(_document)

@public
@constant
def getDocumentInfos(_hash:bytes32) -> (uint256,timestamp):
    infos : CertInfo = self.documentInfos[_hash]
    return(infos.status,infos.lastTime)

@public
@constant
def getAllOwnerInfos() -> address[4]:
    infos:address[4]
    infos[0] = self.majorOwner
    infos[1] = self.minorOwner
    infos[2] = self.newMajorOwner
    infos[3] = self.newMinorOwner
    return infos
